package com.yc.bbs.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

@Component
@ServerEndpoint("/talk/{id}")
public class TalkDo {

    //在线用户容器
    private static Map<String,Session> onlines = new ConcurrentHashMap<>();

    @OnOpen
    public void onOpen(Session session, @PathParam("id") String id) {
        session.getUserProperties().put("id",id);
        onlines.put(id,session);
        String json = buildMsg(id,"上线了",true);
        sendAllMsg(json);
    }

    @OnClose
    public void onClose(Session session) {
        Object id = session.getUserProperties().get("id");
        onlines.remove(id);
        String json = buildMsg((String) id,"下线了",true);
        sendAllMsg(json);
    }

    @OnError
    public void onError(Session session, Throwable throwable) {
        System.out.println("会话异常：" + throwable);
    }

    @OnMessage
    public void onMessage(Session session, String message) {
        Object id = session.getUserProperties().get("id");
        String json = buildMsg((String) id,message,false);
        sendAllMsg(json);

    }

    private void sendAllMsg(String message){
        onlines.values().forEach(s->{
            try {
                s.getBasicRemote().sendText(message);
            } catch (IOException e) {
                throw new RuntimeException("发送信息失败!",e);
            }
        });
    }


    ObjectMapper objectMapper = new ObjectMapper();
    public String buildMsg(String author,String content,boolean isOnlines){
        Msg msg = new Msg(author,content,null);
        if(isOnlines == true){
            List<Object> onlinesId = onlines.values()
                    .stream()
                    .map(session -> session.getUserProperties().get("id"))
                    .collect(Collectors.toList());
            msg.onlines = onlinesId;
        }
        try {
            return objectMapper.writeValueAsString(msg);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("转换信息错误!",e);
        }
    }

}

@Data
@AllArgsConstructor
@NoArgsConstructor
class Msg{
    //发送人
    String author;
    //内容
    String content;
    //在线人员列表
    List<Object> onlines;
}